import mediapipe as mp
import cv2


class HandDetect():

    def __init__(self, mode=False, maxHands=2, minDetectionCon=0.5, minTrackCon=0.5):
        self.mode = mode
        self.maxHands = maxHands
        self.minDetectionCon = minDetectionCon
        self.minTrackCon = minTrackCon

        self.mpHands = mp.solutions.hands
        self.hands = self.mpHands.Hands(self.mode, self.maxHands, 1, self.minDetectionCon, self.minTrackCon)
        self.mpDraw = mp.solutions.drawing_utils

        self.mp_drawing_styles = mp.solutions.drawing_styles

    def findHandsStatus(self, img, draw=True, flipType=True):
        # 图片格式转化
        imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        # img = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
        # 检测图片
        self.results = self.hands.process(imgRGB)
        allHands = []
        # 彩色三通道[高、宽、通道数]
        h, w, c = img.shape
        if self.results.multi_hand_landmarks:
            for handType, handLms in zip(self.results.multi_handedness, self.results.multi_hand_landmarks):
                myhand = {}
                # 手部参数
                lmList = []
                xList = []
                yList = []
                for id, lm in enumerate(handLms.landmark):
                    px, py = int(lm.x * w), int(lm.y * h)
                    lmList.append([px, py])
                    xList.append(px)
                    yList.append(py)

                # 手部边缘参数
                xmin, ymin = min(xList), min(yList)
                xmax, ymax = max(xList), max(yList)
                boxW = xmax - xmin
                boxH = ymax - ymin
                # 手部中心点
                hx = xmin + boxW // 2
                hy = ymin + boxH // 2

                # 保存手部信息
                myhand["lmList"] = lmList
                myhand["hBox"] = xmin, ymin, boxW, boxH
                myhand["center"] = (hx, hy)

                # 检测左右手
                if flipType:
                    if handType.classification[0].label == "Right":
                        myhand["type"] = "Right"
                    else:
                        myhand["type"] = "Left"
                else:
                    myhand["type"] = handType.classification[0].label
                allHands.append(myhand)
                # 绘制图形
                if draw:
                    # 绘制21点
                    self.mpDraw.draw_landmarks(img, handLms, self.mpHands.HAND_CONNECTIONS)
                    # 根据手部边缘信息绘制一个矩形
                    cv2.rectangle(img, (xmin - 20, ymin - 20), (xmin + boxW + 20, ymin + boxH + 20), (255, 0, 255), 2)
                    cv2.putText(img, myhand["type"], (xmin - 30, ymin - 30), cv2.FONT_HERSHEY_PLAIN, 2, (255, 255, 0),
                                2)
        if draw:
            return allHands, img
        else:
            return allHands



    def findHands(self, img, isDraw=True, flipType=True):
        allHands = []
        myHand = {}
        # 转换
        imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        # print("这是一次")
        self.results = self.hands.process(imgRGB)
        if self.results.multi_hand_landmarks:
            for handType, handLms in zip(self.results.multi_handedness, self.results.multi_hand_landmarks):
                if flipType:
                    print(handType.classification[0].label)
                    # if handType.classification[0].label == "Right":
                    #     # myHand["type"] = "Left"
                    #
                    #     # print("加入左手")
                    # else:
                    # myHand["type"] = "Right"
                    # print("加入右手")
                else:
                    myHand["type"] = handType.classification[0].label
                allHands.append(myHand)
                # print(allHands)

                print("==============")
                if isDraw:
                    self.mpDraw.draw_landmarks(img, handLms, self.mpHands.HAND_CONNECTIONS,
                                               self.mp_drawing_styles.get_default_hand_landmarks_style(),
                                               self.mp_drawing_styles.get_default_hand_connections_style())
        return allHands

    def findPosition(self, img, handNo=0, isDraw=True):
        lmList = []
        xList = []
        yList = []
        if self.results.multi_hand_landmarks:
            myHand = self.results.multi_hand_landmarks[handNo]
            # 得到21点的坐标
            for id, lm in enumerate(myHand.landmark):
                height, width, c = img.shape
                cx, cy = int(lm.x * width), int(lm.y * height)
                # print(id,cx,cy)
                lmList.append([id, cx, cy])
                # xList.append(cx)
                # yList.append(cy)
                # # maxX,minX = max(xList), min(xList)
                # # maxY,minY = max(yList), min(yList)
                # # cv2.rectangle(img,(minX,minY),(maxX,maxY),color=(255,0,0),thickness=2)
                # # cv2.rectangle(img, (240, 0), (480, 375), (0, 255, 0), 2)
                # cv2.circle(img, (cx, cy), 10, (0, 100, 100), cv2.FILLED)
        return lmList

    def getNumberOfHands(self):
        return len(self.results.multi_hand_landmarks) if self.results.multi_hand_landmarks != None else 0
